package com.kh.filter;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.wisdge.web.filters.XSSPreventionFilter;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.Normalizer;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @projectName: ngsapitask-ms
 * @package: com.kh.filter
 * @className: XssFilter
 * @author: LiJT
 * @description: TODO
 * @date: 2024-01-12 00:03
 * @version: 1.0
 */

public class XssFilterUtils {
    private static final String[] filterLabels = new String[]{"applet", "blink", "frameset", "iframe", "object", "base", "body", "head", "layer", "style", "basefont", "embed", "html", "link", "title", "bgsound", "frame", "ilayer", "meta", "script"};
    private static final String[] filterAttributes = new String[]{"dynsrc", "action", "background", "bgsound", "lowsrc", "value"};
    private static final String[] filterKeywords = new String[]{"vbscript:", "ms-its:", "firefoxurl:", "javascript:", "mhtml:", "mocha:", "data:", "livescript:"};

    public static String stripXSS(String value) {
        String cleanValue = null;
        if (value != null) {
            cleanValue = filter(value);
            String[] allDomainsArr = null;
            Pattern scriptPattern = Pattern.compile("src[\r\n\\s]*=[\r\n\\s]*(\\\"|'|\\\\\")(.*?)(\\\"|'|\\\\\")", 42);
            Matcher srcMatcher = scriptPattern.matcher(cleanValue);

            while (true) {
                String gp;
                boolean findAllowDomain;
                do {
                    int gc;
                    do {
                        if (!srcMatcher.find()) {
                            return cleanValue;
                        }

                        gc = srcMatcher.groupCount();
                    } while (gc < 1);

                    gp = srcMatcher.group(2);
                    findAllowDomain = false;
                } while (gp == null);

                gp = gp.toLowerCase();
                if (!gp.startsWith("http://") && !gp.startsWith("https://")) {
                    findAllowDomain = true;
                } else {
                    String[] var9 = allDomainsArr;
                    int var10 = allDomainsArr.length;

                    for (int var11 = 0; var11 < var10; ++var11) {
                        String allowDomain = var9[var11];
                        if (gp.startsWith(allowDomain)) {
                            findAllowDomain = true;
                            break;
                        }
                    }
                }

                if (!findAllowDomain) {
                    scriptPattern = Pattern.compile("src[\r\n\\s]*=[\r\n\\s]*(\\\"|'|\\\\\")" + gp + "(\\\"|'|\\\\\")", 42);
                    cleanValue = scriptPattern.matcher(cleanValue).replaceAll("");
                }
            }

        }

        return cleanValue;
    }

    public static String filter(String value) {
        String cleanValue = Normalizer.normalize(value, Normalizer.Form.NFD);
        cleanValue = cleanValue.replaceAll("\u0000", "").replaceAll("'", "");
        Pattern scriptPattern = Pattern.compile("<script>(.*?)</script>", 2);
        cleanValue = scriptPattern.matcher(cleanValue).replaceAll("");
        scriptPattern = Pattern.compile("eval\\((.*?)\\)", 42);
        cleanValue = scriptPattern.matcher(cleanValue).replaceAll(" ");
        scriptPattern = Pattern.compile("expression\\((.*?)\\)", 42);
        cleanValue = scriptPattern.matcher(cleanValue).replaceAll(" ");
        scriptPattern = Pattern.compile("onload(.*?)=", 42);
        cleanValue = scriptPattern.matcher(cleanValue).replaceAll(" ");
        scriptPattern = Pattern.compile("alert\\((.*?)\\)", 42);
        cleanValue = scriptPattern.matcher(cleanValue).replaceAll("");
        String[] var3 = filterAttributes;
        int var4 = var3.length;

        int var5;
        String filterLabel;
        for (var5 = 0; var5 < var4; ++var5) {
            filterLabel = var3[var5];
            scriptPattern = Pattern.compile(filterLabel + "[\r\n]*=[\r\n]*(\\\"|')(.*?)(\\\"|')", 42);
            cleanValue = scriptPattern.matcher(cleanValue).replaceAll(" ");
        }

        var3 = filterKeywords;
        var4 = var3.length;

        for (var5 = 0; var5 < var4; ++var5) {
            filterLabel = var3[var5];
            scriptPattern = Pattern.compile(filterLabel, 2);
            cleanValue = scriptPattern.matcher(cleanValue).replaceAll(" ");
        }

        var3 = filterLabels;
        var4 = var3.length;

        for (var5 = 0; var5 < var4; ++var5) {
            filterLabel = var3[var5];
            scriptPattern = Pattern.compile("<" + filterLabel + "(.*?)>", 42);
            cleanValue = scriptPattern.matcher(cleanValue).replaceAll(" ");
            scriptPattern = Pattern.compile("</" + filterLabel + ">", 2);
            cleanValue = scriptPattern.matcher(cleanValue).replaceAll(" ");
        }

        cleanValue = cleanEventAttact(cleanValue);
        cleanValue = cleanValue.replaceAll("<", "&lt;").replaceAll(">", "&gt;");
        return cleanValue;
    }

    public static String cleanEventAttact(String value) {
        Pattern compile = Pattern.compile("onafterprint(.*?)=", 42);
        value = compile.matcher(value).replaceAll("");
        compile = Pattern.compile("onbeforeprint(.*?)=", 42);
        value = compile.matcher(value).replaceAll("");
        compile = Pattern.compile("onbeforeunload(.*?)=", 42);
        value = compile.matcher(value).replaceAll("");
        compile = Pattern.compile("onerror(.*?)=", 42);
        value = compile.matcher(value).replaceAll("");
        compile = Pattern.compile("onhaschange(.*?)=", 42);
        value = compile.matcher(value).replaceAll("");
        compile = Pattern.compile("onload(.*?)=", 42);
        value = compile.matcher(value).replaceAll("");
        compile = Pattern.compile("onmessage(.*?)=", 42);
        value = compile.matcher(value).replaceAll("");
        compile = Pattern.compile("onoffline(.*?)=", 42);
        value = compile.matcher(value).replaceAll("");
        compile = Pattern.compile("ononline(.*?)=", 42);
        value = compile.matcher(value).replaceAll("");
        compile = Pattern.compile("onpagehide(.*?)=", 42);
        value = compile.matcher(value).replaceAll("");
        compile = Pattern.compile("onpageshow(.*?)=", 42);
        value = compile.matcher(value).replaceAll("");
        compile = Pattern.compile("onpopstate(.*?)=", 42);
        value = compile.matcher(value).replaceAll("");
        compile = Pattern.compile("onredo(.*?)=", 42);
        value = compile.matcher(value).replaceAll("");
        compile = Pattern.compile("onresize(.*?)=", 42);
        value = compile.matcher(value).replaceAll("");
        compile = Pattern.compile("onstorage(.*?)=", 42);
        value = compile.matcher(value).replaceAll("");
        compile = Pattern.compile("onundo(.*?)=", 42);
        value = compile.matcher(value).replaceAll("");
        compile = Pattern.compile("onunload(.*?)=", 42);
        value = compile.matcher(value).replaceAll("");
        compile = Pattern.compile("onblur(.*?)=", 42);
        value = compile.matcher(value).replaceAll("");
        compile = Pattern.compile("onchange(.*?)=", 42);
        value = compile.matcher(value).replaceAll("");
        compile = Pattern.compile("oncontextmenu(.*?)=", 42);
        value = compile.matcher(value).replaceAll("");
        compile = Pattern.compile("onfocus(.*?)=", 42);
        value = compile.matcher(value).replaceAll("");
        compile = Pattern.compile("onformchange(.*?)=", 42);
        value = compile.matcher(value).replaceAll("");
        compile = Pattern.compile("onforminput(.*?)=", 42);
        value = compile.matcher(value).replaceAll("");
        compile = Pattern.compile("oninput(.*?)=", 42);
        value = compile.matcher(value).replaceAll("");
        compile = Pattern.compile("oninvalid(.*?)=", 42);
        value = compile.matcher(value).replaceAll("");
        compile = Pattern.compile("onreset(.*?)=", 42);
        value = compile.matcher(value).replaceAll("");
        compile = Pattern.compile("onselect(.*?)=", 42);
        value = compile.matcher(value).replaceAll("");
        compile = Pattern.compile("onsubmit(.*?)=", 42);
        value = compile.matcher(value).replaceAll("");
        compile = Pattern.compile("onkeydown(.*?)=", 42);
        value = compile.matcher(value).replaceAll("");
        compile = Pattern.compile("onkeypress(.*?)=", 42);
        value = compile.matcher(value).replaceAll("");
        compile = Pattern.compile("onkeyup(.*?)=", 42);
        value = compile.matcher(value).replaceAll("");
        compile = Pattern.compile("onclick(.*?)=", 42);
        value = compile.matcher(value).replaceAll("");
        compile = Pattern.compile("ondblclick(.*?)=", 42);
        value = compile.matcher(value).replaceAll("");
        compile = Pattern.compile("ondrag(.*?)=", 42);
        value = compile.matcher(value).replaceAll("");
        compile = Pattern.compile("ondragend(.*?)=", 42);
        value = compile.matcher(value).replaceAll("");
        compile = Pattern.compile("ondragenter(.*?)=", 42);
        value = compile.matcher(value).replaceAll("");
        compile = Pattern.compile("ondragleave(.*?)=", 42);
        value = compile.matcher(value).replaceAll("");
        compile = Pattern.compile("ondragover(.*?)=", 42);
        value = compile.matcher(value).replaceAll("");
        compile = Pattern.compile("ondragstart(.*?)=", 42);
        value = compile.matcher(value).replaceAll("");
        compile = Pattern.compile("ondrop(.*?)=", 42);
        value = compile.matcher(value).replaceAll("");
        compile = Pattern.compile("onmousedown(.*?)=", 42);
        value = compile.matcher(value).replaceAll("");
        compile = Pattern.compile("onmousemove(.*?)=", 42);
        value = compile.matcher(value).replaceAll("");
        compile = Pattern.compile("onmouseout(.*?)=", 42);
        value = compile.matcher(value).replaceAll("");
        compile = Pattern.compile("onmouseover(.*?)=", 42);
        value = compile.matcher(value).replaceAll("");
        compile = Pattern.compile("onmouseenter(.*?)=", 42);
        value = compile.matcher(value).replaceAll("");
        compile = Pattern.compile("onmouseup(.*?)=", 42);
        value = compile.matcher(value).replaceAll("");
        compile = Pattern.compile("onmousewheel(.*?)=", 42);
        value = compile.matcher(value).replaceAll("");
        compile = Pattern.compile("onscroll(.*?)=", 42);
        value = compile.matcher(value).replaceAll("");
        value = value.replace("document", "");
        value = value.replace("alert", "");
        return value;
    }
}